<template>
  <BaseDialog
    v-model="dialogVisible"
    :title="g_t('fleet.addressSelect')"
    width="850px"
    style="width: 850px"
    :before-close="handleClose"
  >
    <div class="map-container">
      <el-autocomplete
        class="search-input"
        v-model="keyword"
        value-key="value"
        :fetch-suggestions="querySearchAsync"
        :placeholder="g_t('fleet.searchPlaceholder')"
        @select="handleSelect"
      >
        <template #default="{ item }">
          <div class="address-item">
            <div class="name">{{ item.name }}</div>
            <span class="address">{{ item.address }}</span>
          </div>
        </template>
      </el-autocomplete>
      <div id="locationMap"></div>
    </div>
    <template #footer>
      <div class="form-dialog-footer">
        <el-button plain @click="handleClose">{{
          $t('public.cancel')
        }}</el-button>
        <el-button type="primary" @click="handleSubmitForm">{{
          $t('public.confirm')
        }}</el-button>
      </div>
    </template>
  </BaseDialog>
</template>

<script setup>
import markerIcon from '@/assets/map/marker.png'

const props = defineProps({
  regionName: {
    type: String,
    default: ''
  },
  type: {
    type: String,
    default: ''
  }
})

const emit = defineEmits(['add'])
const dialogVisible = defineModel({
  type: Boolean,
  default: false
})
const baseMapMixin = useBaseMapMixin({
  satelliteMap: false,
  mapId: 'locationMap',
  zoom: 14
})
const deviceLabelsLayer = new AMap.LabelsLayer({
  zIndex: 300, // 海量点图层叠加的顺序
  zooms: [4, 20], // 在指定地图缩放级别范围内展示海量点图层
  collision: false
})
// 初始化 Geocoder
const geocoder = new AMap.Geocoder({
  city: '全国' // 城市，默认："全国"
})
const keyword = ref('')
let addressInfo = {
  regionCode: [],
  regionName: '',
  address: '',
  lnglat: []
}
let marker = null

onMounted(() => {
  nextTick(() => {
    baseMapMixin.initMapModel()
    baseMapMixin.aMapScale.value.hide()
    initMapCenter()
    mapClick()
  })
})

onUnmounted(() => {
  const map = baseMapMixin.map.value
  if (map) {
    map.off('click')
    if (marker) {
      deviceLabelsLayer.remove([marker])
      marker = null
    }
    map.clearMap()
  }
})

const initMapCenter = () => {
  // 正向地理编码
  geocoder.getLocation(props.regionName, (status, result) => {
    console.log('geocoder.getLocation', status, result)
    if (status === 'complete' && result.info === 'OK') {
      const lnglats = result.geocodes[0].location
      baseMapMixin.map.value.setCenter(lnglats)
    }
  })
}
const mapClick = _ => {
  baseMapMixin.map.value.on('click', e => {
    // console.log('map.on(click)', e)
    addressInfo.lnglat = [e.lnglat.lng, e.lnglat.lat] // 获取点击位置的经纬度
    getAddress().then(data => {
      const { addressComponent, formattedAddress } = data
      keyword.value = formattedAddress.replace(
        addressComponent.province +
          addressComponent.city +
          addressComponent.district,
        ''
      )
      addressInfo.address = keyword.value
    })
  })
}

const getAddress = _ => {
  return new Promise((resolve, reject) => {
    // 使用 Geocoder 反向地理编码
    geocoder.getAddress(addressInfo.lnglat, (status, result) => {
      // console.log('geocoder.getAddress', status, result)
      if (status === 'complete' && result.info === 'OK') {
        resolve(result.regeocode)
        const { addressComponent } = result.regeocode
        const regionData = g_utils.getRegionData(
          addressComponent.province + addressComponent.city
        )
        addressInfo = {
          ...addressInfo,
          regionCode: regionData.codeArr,
          regionName: regionData.nameArr.join('/')
        }
        nextTick(() => {
          addMarker()
        })
        console.log('addressInfo', addressInfo)
      } else {
        if (status === 'no_data') {
          ElMessage.warning(g_t('fleet.notFoundAddress'))
        } else {
          ElMessage.error(g_t('fleet.getAddressFailed'))
        }
        console.error('获取地址失败')
      }
    })
  })
}

const handleClose = _ => {
  dialogVisible.value = false
}

const querySearchAsync = g_.debounce(async (queryString, cb) => {
  const data = await autoInput()
  cb(data)
}, 300)

const handleSelect = item => {
  // console.log('handleSelect', item)
  keyword.value = item.name
  addressInfo.address = keyword.value
  addressInfo.lnglat = [item.location.lng, item.location.lat]
  getAddress()
}

// 实例化点标记
const addMarker = () => {
  const map = baseMapMixin.map.value
  map.setCenter(addressInfo.lnglat)
  map.setZoom(14)
  if (marker) {
    marker.setPosition(addressInfo.lnglat)
    marker.setText({
      content: keyword.value
    })
  } else {
    marker = new AMap.LabelMarker({
      position: addressInfo.lnglat,
      icon: {
        type: 'image',
        image: markerIcon,
        size: [51 * 0.6, 70 * 0.6],
        // imageSize: [51 * 0.6, 70 * 0.6],
        anchor: 'center'
      },
      text: {
        content: keyword.value
      }
    })
    deviceLabelsLayer.add([marker])
    map.add(deviceLabelsLayer)
  }
}

const autoInput = _ => {
  return new Promise((resolve, reject) => {
    AMap.plugin('AMap.PlaceSearch', function () {
      const placeSearch = new AMap.PlaceSearch()
      placeSearch.search(keyword.value, function (status, result) {
        // 查询成功时，result 即对应匹配的 POI 信息
        // console.log('placeSearch.search', status, result)
        resolve(
          status === 'complete' && result.info === 'OK'
            ? result?.poiList?.pois || []
            : []
        )
      })
    })
  })
}

const handleSubmitForm = () => {
  if (!addressInfo.lnglat.length)
    return ElMessage.error(g_t('fleet.selectLocationTip'))
  handleClose()
  emit('add', props.type, addressInfo)
}
</script>

<style scoped lang="scss">
.map-container {
  position: relative;
  :deep(.search-input) {
    position: absolute;
    left: 5px;
    top: 5px;
    width: auto;
    min-width: 300px;
    z-index: 10;
  }
}
.address-item {
  line-height: 16px;
  margin-bottom: 8px;
  .address {
    color: var(--color-999);
  }
}
#locationMap {
  width: 100%;
  height: calc(100vh - 200px);
  @extend .user-select-none;

  :deep(.amap-logo) {
    display: none !important;
  }
}
.form-dialog-footer {
  padding-top: 10px;
}
</style>
